<!DOCTYPE html>
<html>
<head>
    <title>repeat</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <script src="./vendor/avalon/avalon.js" ></script>
    <style>
        .ms-tabs{
            border: 1px solid black;
            padding: 1em;
            width:300px;
            height:100px;
        }
        .ms-tigger{
            background:#DDD;
            margin-right:1em;
        }
        .ms-active{
            background:#CD235C;
        }

        .last{
            background: purple;
        }
        .first{
            background:violet;
        }
    </style>
    <script type="text/javascript">
        var model1 = avalon.define({
            $id: "test1",
            array: ["aaa","bbb","ccc"]
        })


        var model2 = avalon.define({
            $id: "test2",
            array: ["aaa", "bbb", "ccc"],
            currentIndex: 0,
            changeIndex: function(i) {
                model2.currentIndex = i
            }
        })


        var model3 = avalon.define({
            $id: "test3",
            array: ["aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg"]
        })


        var model4 = avalon.define({
            $id: "test4",
            array: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
        })

        var model5 = avalon.define({
            $id: "test5",
            num: [1,2,3],
            data: ["a", "b", "c"]
        });


        avalon.define("test6", function(vm) {//这里是使用avalon.define的旧风格
            vm.array = ["1", "2", "3", "4"]
            "push,unshift,remove,ensure".replace(/\w+/g, function(method) {
                vm[method] = function(e) {
                    if (this.value && e.which == 13) {//this为input元素
                        vm.array[method](this.value);
                        this.value = "";
                    }
                }
            })

            vm.removeAt = function(e) {
                if (isFinite(this.value) && e.which == 13) {//this为input元素
                    var a = ~~this.value
                    vm.array.removeAt(a)
                    this.value = "";
                }
            }
            "pop,shift,sort,reverse".replace(/\w+/g, function(method) {
                vm[method] = function(e) {
                    vm.array[method]();
                }
            })
        })



        var model7 = avalon.define({
            $id: "test7",
            data: [{checked: false}, {checked: false}, {checked: false}],
            allchecked: false,
            /*checkAll: function() {
                var bool = model7.allchecked = this.checked
                model7.data.forEach(function(el) {
                    el.checked = bool
                })
            },*/
            checkOne: function() {
                if (!this.checked) {
                    model7.allchecked = false
                } else {//avalon已经为数组添加了ecma262v5的一些新方法
                    model7.allchecked = model7.data.every(function(el) {
                        return el.checked
                    })
                }
            }
        })
        model7.$watch("allchecked", function(newVal, oldVal) {
            console.log(newVal, oldVal)
            var bool = newVal
            model7.data.forEach(function(el) {
                el.checked = bool
            })
        })


        var index8 = 0
        var model8 = avalon.define({
            $id: "test8",
            data:{
                aaa: 1111,
                bbb: 2222,
                ccc: 3333,
                ddd: 4444
            },
            getIndex: function(){
                return index8++
            }
        })


        var index9 = 0
        var model9 = avalon.define({
            $id: "test9",
            data:{
                aaa: 1111,
                bbb: 2222,
                ccc: 3333,
                ddd: 4444
            },
            keys: function(a){
                console.log(a)
                console.log(this)
                // 如果数组里有data不存在的key，会报错
                return  ["ccc","ddd","aaa"]
            },
            getIndex: function(){
                return index9++
            }
        })


        var model10 = avalon.define({
            $id: "test10",
            data: [
                {text: "title1", value: 111111},
                {text: "title2", value: 222222},
                {text: "title3", value: 333333}
            ]
        })

    </script>
        
</head>
<body>
    <div  ms-controller="test1">
        <ul>
            <li ms-repeat="array">{{el}} --- {{$index}}</li>
        </ul>
        <ul>
            <li ms-repeat-item="array">{{item}} --- {{$index}}</li>
        </ul>
    </div>


    <div ms-controller="test2">
        <button type="button"
                class="ms-tigger"
                ms-repeat="array" 
                ms-class="ms-active: currentIndex === $index" 
                ms-click="changeIndex($index)">切换键{{$index+1}}</button>
        <div class="ms-tabs"
             ms-repeat="array"
             ms-if-loop="currentIndex == $index">{{el}}</div>
    </div>


    <div ms-controller="test3">
        <!-- 
            $index，这个一个数字，为元素对应的索引值
            $first，这是一个布尔，判定它是否第一个
            $last，这是一个布尔，判定它是否最后一个
            $remove，这是一个方法，移除此数组元素
            $outer，这是一个对象，用于获取外围循环中的VM对象，它里面包含$index, $first, $last, $remove等属性。
         -->
        <ul>
            <li ms-repeat-xx="array" 
                ms-class="last: $last" 
                ms-class-1="first: $first" 
                ms-click="$remove">{{xx}}:{{$index}}</li>
        </ul>
    </div>


    <div ms-controller="test4">
        <table border="1">
            <tr ms-repeat-el="array">
                <td ms-repeat-elem="el">{{elem}}  它位于第<b style="color:orchid">{{$outer.$index}}</b>行</td>
            </tr>
        </table>
    </div>


    <div ms-controller="test5">
        <div ms-repeat="num">
            <strong ms-repeat="data">
                {{el}}: {{$outer.el}}
            </strong>
        </div>
    </div>


    <div ms-controller="test6">
        <p>监控数组拥有以下方法，我们可以操作它们就能同步对应的区域</p>
        <blockquote>
            push, pushAll, shift, unshift, pop, slice, splice, remove, removeAt, removeAll, clear, ensure, sort, reverse, set
        </blockquote>
        <ul>
            <li  ms-repeat="array">数组的第{{$index+1}}个元素为{{el}}</li>
        </ul>
        <p>对数组进行push操作，并回车<input ms-keypress="push"></p>
        <p>对数组进行unshift操作，并回车<input ms-keypress="unshift"></p>
        <p>对数组进行ensure操作，并回车<input ms-keypress="ensure"><br/>
            (只有数组不存在此元素才push进去)</p>
        <p>对数组进行remove操作，并回车<input ms-keypress="remove"></p>
        <p>对数组进行removeAt操作，并回车<input ms-keypress="removeAt"></p>
        <p><button type="button" ms-click="sort">对数组进行sort操作</button></p>
        <p><button type="button" ms-click="reverse">对数组进行reverse操作</button></p>
        <p><button type="button" ms-click="shift">对数组进行shift操作</button></p>
        <p><button type="button" ms-click="pop">对数组进行pop操作</button></p>
        <p>当前数组的长度为<span style="color:red">{{array.size()}}</span>，注意 我们无法修改数组length的固有行为，因此它无法同步视图，需要用size方法。</p>
    </div>


    <table ms-controller="test7" border="1">
        <tr>
            <!-- <td><input type="checkbox" ms-duplex-radio="allchecked" data-duplex-changed="checkAll"/>全选</td> -->
            <td><input type="checkbox" ms-duplex-radio="allchecked"/>全选</td>
        </tr>
        <tr ms-repeat="data">
            <td><input type="checkbox" ms-duplex-radio="el.checked" ms-data-index=$index data-duplex-changed="checkOne"/>xxxxxxxxxxxx</td>
        </tr>
    </table>


    <!-- 对于哈希，ms-repeat内部只会产生$key、 $val、 $outer三个变量，不存在$index什么的。$key就是属性名，$val就是属性值，$outer与之前的讲解相同 -->
    <div ms-controller="test8">
        <ul>
            <li ms-repeat="data" >{{getIndex()}}、{{$key}}--{{$val}}</li>
        </ul>
    </div>



    <!-- 如果我们想控制对象属性的输出顺序，或让某些元素不输出来，那么我们可以使用data-with-sorted回调。它用ms-repeat、ms-with绑定，赶对象渲染之前触发，要求输出一个字符串数组，对象的键值对会根据它依次输出；框架默认会输入原对象的所有键名构成的数组作为参数。 -->
    <div ms-controller="test9">
        <ul>
            <li ms-repeat="data" data-with-sorted="keys" >{{getIndex()}}、{{$key}}--{{$val}}</li>
        </ul>
    </div>



    <!-- ms-repeat只能循环自身，如果有时我们碰到一些复杂的结构，如定义列表，那么我们可以使用ms-each、 ms-with。ms-each是用于循环对象，ms-with是循环对象。除了循环范围不一样外，其他与ms-repeat没什么不同。 -->
    <div ms-controller="test10">
        <dl ms-each="data">
            <dt>{{el.text}}</dt>
            <dd>{{el.value}}</dd>
        </dl>
    </div>

</body>
</html>
